using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;

namespace MatrixFramework.Shared.Domain.Photos.Compression
{
    /// <summary>
    /// 照片压缩实体
    /// 支持多种压缩算法和格式转换功能
    /// </summary>
    public class PhotoCompression : FullAuditedEntity<Guid>, IMultiTenant
    {
        /// <summary>
        /// 租户ID
        /// </summary>
        public virtual Guid? TenantId { get; protected set; }

        /// <summary>
        /// 照片ID
        /// </summary>
        public virtual Guid PhotoId { get; protected set; }

        /// <summary>
        /// 压缩类型
        /// </summary>
        public virtual CompressionType CompressionType { get; protected set; }

        /// <summary>
        /// 压缩状态
        /// </summary>
        public virtual CompressionStatus Status { get; protected set; }

        /// <summary>
        /// 压缩引擎
        /// </summary>
        [Required]
        [MaxLength(100)]
        public virtual string Engine { get; protected set; }

        /// <summary>
        /// 引擎版本
        /// </summary>
        [MaxLength(50)]
        public virtual string EngineVersion { get; protected set; }

        /// <summary>
        /// 压缩参数
        /// </summary>
        public virtual Dictionary<string, object> Parameters { get; protected set; }

        /// <summary>
        /// 原始文件大小（字节）
        /// </summary>
        public virtual long OriginalFileSize { get; protected set; }

        /// <summary>
        /// 压缩后文件大小（字节）
        /// </summary>
        public virtual long CompressedFileSize { get; protected set; }

        /// <summary>
        /// 压缩比例
        /// </summary>
        public virtual double CompressionRatio { get; protected set; }

        /// <summary>
        /// 质量评分
        /// </summary>
        public virtual double QualityScore { get; protected set; }

        /// <summary>
        /// 目标格式
        /// </summary>
        [MaxLength(10)]
        public virtual string TargetFormat { get; protected set; }

        /// <summary>
        /// 原始格式
        /// </summary>
        [MaxLength(10)]
        public virtual string OriginalFormat { get; protected set; }

        /// <summary>
        /// 目标尺寸
        /// </summary>
        public virtual TargetDimensions TargetDimensions { get; protected set; }

        /// <summary>
        /// 压缩时间
        /// </summary>
        public virtual DateTime? CompressionTime { get; protected set; }

        /// <summary>
        /// 执行耗时（毫秒）
        /// </summary>
        public virtual long ExecutionDuration { get; protected set; }

        /// <summary>
        /// 优先级
        /// </summary>
        public virtual CompressionPriority Priority { get; protected set; }

        /// <summary>
        /// 是否保持宽高比
        /// </summary>
        public virtual bool PreserveAspectRatio { get; protected set; }

        /// <summary>
        /// 是否渐进式JPEG
        /// </summary>
        public virtual bool IsProgressive { get; protected set; }

        /// <summary>
        /// 是否优化文件大小
        /// </summary>
        public virtual bool OptimizeFileSize { get; protected set; }

        /// <summary>
        /// 压缩配置
        /// </summary>
        public virtual CompressionConfiguration Configuration { get; protected set; }

        /// <summary>
        /// 压缩结果
        /// </summary>
        public virtual CompressionResult Result { get; protected set; }

        /// <summary>
        /// 性能指标
        /// </summary>
        public virtual CompressionMetrics Metrics { get; protected set; }

        /// <summary>
        /// 压缩历史
        /// </summary>
        public virtual List<CompressionHistory> History { get; protected set; }

        /// <summary>
        /// 照片导航属性
        /// </summary>
        public virtual Photo Photo { get; protected set; }

        protected PhotoCompression()
        {
            Parameters = new Dictionary<string, object>();
            TargetDimensions = new TargetDimensions();
            Configuration = new CompressionConfiguration();
            Result = new CompressionResult();
            Metrics = new CompressionMetrics();
            History = new List<CompressionHistory>();
        }

        public PhotoCompression(
            Guid id,
            Guid photoId,
            CompressionType compressionType,
            string targetFormat = null,
            TargetDimensions targetDimensions = null,
            Dictionary<string, object> parameters = null,
            Guid? tenantId = null) : base(id)
        {
            PhotoId = photoId;
            CompressionType = compressionType;
            TargetFormat = targetFormat;
            TargetDimensions = targetDimensions ?? new TargetDimensions();
            Parameters = parameters ?? new Dictionary<string, object>();
            TenantId = tenantId;
            Status = CompressionStatus.Pending;
            Priority = CompressionPriority.Normal;
            PreserveAspectRatio = true;

            Configuration = new CompressionConfiguration();
            Result = new CompressionResult();
            Metrics = new CompressionMetrics();
            History = new List<CompressionHistory>();
        }

        /// <summary>
        /// 开始压缩
        /// </summary>
        public virtual void StartCompression()
        {
            if (Status != CompressionStatus.Pending && Status != CompressionStatus.Retrying)
                throw new InvalidOperationException($"无法在状态 {Status} 下开始压缩");

            Status = CompressionStatus.Running;
            CompressionTime = DateTime.Now;
            AddHistory(CompressionAction.Started, "开始压缩照片");
        }

        /// <summary>
        /// 完成压缩
        /// </summary>
        public virtual void CompleteCompression(long compressedFileSize, double qualityScore, long executionDuration)
        {
            Status = CompressionStatus.Completed;
            CompressedFileSize = compressedFileSize;
            QualityScore = qualityScore;
            ExecutionDuration = executionDuration;

            if (OriginalFileSize > 0)
            {
                CompressionRatio = (double)compressedFileSize / OriginalFileSize;
            }

            // 更新性能指标
            Metrics.UpdateMetrics(this);

            // 更新结果
            Result.IsSuccess = true;
            Result.CompressionRatio = CompressionRatio;
            Result.QualityScore = QualityScore;
            Result.ExecutionDuration = executionDuration;

            AddHistory(CompressionAction.Completed, $"压缩完成，压缩比: {CompressionRatio:P2}, 质量评分: {qualityScore:F2}");
        }

        /// <summary>
        /// 压缩失败
        /// </summary>
        public virtual void FailCompression(string errorMessage)
        {
            Status = CompressionStatus.Failed;
            Result.IsSuccess = false;
            Result.ErrorMessage = errorMessage;
            AddHistory(CompressionAction.Failed, $"压缩失败: {errorMessage}");
        }

        /// <summary>
        /// 取消压缩
        /// </summary>
        public virtual void CancelCompression(string reason = null)
        {
            Status = CompressionStatus.Cancelled;
            Result.CancelReason = reason;
            AddHistory(CompressionAction.Cancelled, $"压缩已取消: {reason}");
        }

        /// <summary>
        /// 重试压缩
        /// </summary>
        public virtual void RetryCompression()
        {
            if (Metrics.RetryCount >= Configuration.MaxRetryCount)
            {
                FailCompression("已达到最大重试次数");
                return;
            }

            Metrics.RetryCount++;
            Status = CompressionStatus.Retrying;
            CompressionTime = DateTime.Now;
            Result.ErrorMessage = null;
            AddHistory(CompressionAction.Retrying, $"开始重试压缩，重试次数: {Metrics.RetryCount}/{Configuration.MaxRetryCount}");
        }

        /// <summary>
        /// 设置原始文件信息
        /// </summary>
        public virtual void SetOriginalFileInfo(long fileSize, string format)
        {
            OriginalFileSize = fileSize;
            OriginalFormat = format;
        }

        /// <summary>
        /// 更新压缩参数
        /// </summary>
        public virtual void UpdateParameters(Dictionary<string, object> parameters)
        {
            Parameters = parameters ?? new Dictionary<string, object>();
        }

        /// <summary>
        /// 设置压缩参数
        /// </summary>
        public virtual void SetParameter(string key, object value)
        {
            Parameters[key] = value;
        }

        /// <summary>
        /// 更新目标尺寸
        /// </summary>
        public virtual void UpdateTargetDimensions(TargetDimensions dimensions)
        {
            TargetDimensions = dimensions ?? new TargetDimensions();
        }

        /// <summary>
        /// 更新配置
        /// </summary>
        public virtual void UpdateConfiguration(CompressionConfiguration configuration)
        {
            Configuration = configuration ?? new CompressionConfiguration();
        }

        /// <summary>
        /// 添加压缩历史
        /// </summary>
        public virtual void AddHistory(CompressionAction action, string description)
        {
            var history = new CompressionHistory
            {
                Action = action,
                Description = description,
                ActionTime = DateTime.Now
            };

            History.Add(history);
        }

        /// <summary>
        /// 计算压缩统计
        /// </summary>
        public virtual CompressionStatistics GetStatistics()
        {
            return new CompressionStatistics
            {
                OriginalFileSize = OriginalFileSize,
                CompressedFileSize = CompressedFileSize,
                CompressionRatio = CompressionRatio,
                SpaceSaved = OriginalFileSize - CompressedFileSize,
                SpaceSavedPercentage = OriginalFileSize > 0 ? (double)(OriginalFileSize - CompressedFileSize) / OriginalFileSize : 0,
                QualityScore = QualityScore,
                ExecutionDuration = ExecutionDuration,
                CompressionTime = CompressionTime,
                CompressionType = CompressionType,
                TargetFormat = TargetFormat
            };
        }

        /// <summary>
        /// 检查是否可以重试
        /// </summary>
        public virtual bool CanRetry()
        {
            return Metrics.RetryCount < Configuration.MaxRetryCount &&
                   (Status == CompressionStatus.Failed || Status == CompressionStatus.Timeout);
        }

        /// <summary>
        /// 检查是否已完成
        /// </summary>
        public virtual bool IsCompleted()
        {
            return Status == CompressionStatus.Completed ||
                   Status == CompressionStatus.Failed ||
                   Status == CompressionStatus.Cancelled;
        }

        /// <summary>
        /// 估算压缩后文件大小
        /// </summary>
        public virtual long EstimateCompressedSize()
        {
            if (OriginalFileSize <= 0)
                return 0;

            double estimatedRatio = GetEstimatedCompressionRatio();
            return (long)(OriginalFileSize * estimatedRatio);
        }

        /// <summary>
        /// 获取预估压缩比
        /// </summary>
        private double GetEstimatedCompressionRatio()
        {
            // 基于压缩类型和目标格式的预估
            return CompressionType switch
            {
                CompressionType.Lossless => 0.8, // 无损压缩通常能减少20%大小
                CompressionType.Lossy => TargetFormat?.ToUpper() switch
                {
                    "JPEG" => 0.3,  // JPEG通常能减少70%大小
                    "WEBP" => 0.25, // WebP通常能减少75%大小
                    "AVIF" => 0.2,  // AVIF通常能减少80%大小
                    _ => 0.5
                },
                CompressionType.Adaptive => 0.4, // 自适应压缩取中间值
                _ => 0.6
            };
        }
    }

    /// <summary>
    /// 压缩类型枚举
    /// </summary>
    public enum CompressionType
    {
        /// <summary>
        /// 无损压缩
        /// </summary>
        Lossless = 0,

        /// <summary>
        /// 有损压缩
        /// </summary>
        Lossy = 1,

        /// <summary>
        /// 自适应压缩
        /// </summary>
        Adaptive = 2,

        /// <summary>
        /// 智能压缩
        /// </summary>
        Intelligent = 3,

        /// <summary>
        /// 高质量压缩
        /// </summary>
        HighQuality = 4,

        /// <summary>
        /// 平衡压缩
        /// </summary>
        Balanced = 5,

        /// <summary>
        /// 高压缩率
        /// </summary>
        HighCompression = 6,

        /// <summary>
        /// 自定义压缩
        /// </summary>
        Custom = 7
    }

    /// <summary>
    /// 压缩状态枚举
    /// </summary>
    public enum CompressionStatus
    {
        /// <summary>
        /// 等待中
        /// </summary>
        Pending = 0,

        /// <summary>
        /// 运行中
        /// </summary>
        Running = 1,

        /// <summary>
        /// 已完成
        /// </summary>
        Completed = 2,

        /// <summary>
        /// 失败
        /// </summary>
        Failed = 3,

        /// <summary>
        /// 已取消
        /// </summary>
        Cancelled = 4,

        /// <summary>
        /// 重试中
        /// </summary>
        Retrying = 5,

        /// <summary>
        /// 超时
        /// </summary>
        Timeout = 6,

        /// <summary>
        /// 部分成功
        /// </summary>
        PartialSuccess = 7
    }

    /// <summary>
    /// 压缩优先级枚举
    /// </summary>
    public enum CompressionPriority
    {
        /// <summary>
        /// 低优先级
        /// </summary>
        Low = 0,

        /// <summary>
        /// 普通优先级
        /// </summary>
        Normal = 1,

        /// <summary>
        /// 高优先级
        /// </summary>
        High = 2,

        /// <summary>
        /// 紧急优先级
        /// </summary>
        Urgent = 3,

        /// <summary>
        /// 实时优先级
        /// </summary>
        RealTime = 4
    }

    /// <summary>
    /// 目标尺寸
    /// </summary>
    public class TargetDimensions
    {
        /// <summary>
        /// 目标宽度
        /// </summary>
        public int? Width { get; set; }

        /// <summary>
        /// 目标高度
        /// </summary>
        public int? Height { get; set; }

        /// <summary>
        /// 最大宽度
        /// </summary>
        public int? MaxWidth { get; set; }

        /// <summary>
        /// 最大高度
        /// </summary>
        public int? MaxHeight { get; set; }

        /// <summary>
        /// 最小宽度
        /// </summary>
        public int? MinWidth { get; set; }

        /// <summary>
        /// 最小高度
        /// </summary>
        public int? MinHeight { get; set; }

        /// <summary>
        /// 缩放模式
        /// </summary>
        public ResizeMode ResizeMode { get; set; } = ResizeMode.Fit;

        /// <summary>
        /// 是否只缩小不放大
        /// </summary>
        public bool OnlyDownscale { get; set; } = true;

        /// <summary>
        /// 获取是否需要调整尺寸
        /// </summary>
        public bool NeedsResize => Width.HasValue || Height.HasValue || MaxWidth.HasValue || MaxHeight.HasValue;

        /// <summary>
        /// 计算目标尺寸（基于原始尺寸）
        /// </summary>
        public (int width, int height) CalculateTargetSize(int originalWidth, int originalHeight)
        {
            if (!NeedsResize || OnlyDownscale && (originalWidth <= (MaxWidth ?? int.MaxValue) && originalHeight <= (MaxHeight ?? int.MaxValue)))
            {
                return (originalWidth, originalHeight);
            }

            int targetWidth = originalWidth;
            int targetHeight = originalHeight;

            // 处理最大尺寸限制
            if (MaxWidth.HasValue && originalWidth > MaxWidth.Value)
            {
                double ratio = (double)MaxWidth.Value / originalWidth;
                targetWidth = MaxWidth.Value;
                targetHeight = (int)(originalHeight * ratio);
            }

            if (MaxHeight.HasValue && targetHeight > MaxHeight.Value)
            {
                double ratio = (double)MaxHeight.Value / targetHeight;
                targetHeight = MaxHeight.Value;
                targetWidth = (int)(targetWidth * ratio);
            }

            // 处理精确尺寸
            if (Width.HasValue && Height.HasValue)
            {
                targetWidth = Width.Value;
                targetHeight = Height.Value;
            }
            else if (Width.HasValue)
            {
                double ratio = (double)Width.Value / originalWidth;
                targetWidth = Width.Value;
                targetHeight = (int)(originalHeight * ratio);
            }
            else if (Height.HasValue)
            {
                double ratio = (double)Height.Value / originalHeight;
                targetHeight = Height.Value;
                targetWidth = (int)(originalWidth * ratio);
            }

            // 应用缩放模式
            return ResizeMode switch
            {
                ResizeMode.Crop => ApplyCropMode(originalWidth, originalHeight, targetWidth, targetHeight),
                ResizeMode.Fill => ApplyFillMode(originalWidth, originalHeight, targetWidth, targetHeight),
                _ => (targetWidth, targetHeight)
            };
        }

        /// <summary>
        /// 应用裁剪模式
        /// </summary>
        private (int width, int height) ApplyCropMode(int originalWidth, int originalHeight, int targetWidth, int targetHeight)
        {
            double originalRatio = (double)originalWidth / originalHeight;
            double targetRatio = (double)targetWidth / targetHeight;

            if (originalRatio > targetRatio)
            {
                // 原图更宽，以高度为准
                return ((int)(targetHeight * originalRatio), targetHeight);
            }
            else
            {
                // 原图更高，以宽度为准
                return (targetWidth, (int)(targetWidth / originalRatio));
            }
        }

        /// <summary>
        /// 应用填充模式
        /// </summary>
        private (int width, int height) ApplyFillMode(int originalWidth, int originalHeight, int targetWidth, int targetHeight)
        {
            double originalRatio = (double)originalWidth / originalHeight;
            double targetRatio = (double)targetWidth / targetHeight;

            if (originalRatio < targetRatio)
            {
                // 原图更高，以高度为准
                return ((int)(targetHeight * originalRatio), targetHeight);
            }
            else
            {
                // 原图更宽，以宽度为准
                return (targetWidth, (int)(targetWidth / originalRatio));
            }
        }
    }

    /// <summary>
    /// 缩放模式枚举
    /// </summary>
    public enum ResizeMode
    {
        /// <summary>
        /// 适应（保持宽高比）
        /// </summary>
        Fit = 0,

        /// <summary>
        /// 填充（可能裁剪）
        /// </summary>
        Fill = 1,

        /// <summary>
        /// 裁剪到指定尺寸
        /// </summary>
        Crop = 2,

        /// <summary>
        /// 拉伸（不保持宽高比）
        /// </summary>
        Stretch = 3
    }

    /// <summary>
    /// 压缩配置
    /// </summary>
    public class CompressionConfiguration
    {
        /// <summary>
        /// JPEG质量（0-100）
        /// </summary>
        public int JpegQuality { get; set; } = 85;

        /// <summary>
        /// PNG压缩级别（0-9）
        /// </summary>
        public int PngCompressionLevel { get; set; } = 6;

        /// <summary>
        /// WebP质量（0-100）
        /// </summary>
        public int WebPQuality { get; set; } = 80;

        /// <summary>
        /// AVIF质量（0-100）
        /// </summary>
        public int AvifQuality { get; set; } = 75;

        /// <summary>
        /// 是否启用渐进式JPEG
        /// </summary>
        public bool EnableProgressiveJPEG { get; set; } = true;

        /// <summary>
        /// 是否启用优化
        /// </summary>
        public bool EnableOptimization { get; set; } = true;

        /// <summary>
        /// 最大重试次数
        /// </summary>
        public int MaxRetryCount { get; set; } = 3;

        /// <summary>
        /// 超时时间（秒）
        /// </summary>
        public int TimeoutSeconds { get; set; } = 60;

        /// <summary>
        /// 是否启用缓存
        /// </summary>
        public bool EnableCache { get; set; } = true;

        /// <summary>
        /// 缓存有效期（小时）
        /// </summary>
        public int CacheExpiryHours { get; set; } = 24;

        /// <summary>
        /// 支持的输入格式
        /// </summary>
        public List<string> SupportedInputFormats { get; set; } = new() { "JPEG", "PNG", "WEBP", "BMP", "TIFF", "GIF" };

        /// <summary>
        /// 支持的输出格式
        /// </summary>
        public List<string> SupportedOutputFormats { get; set; } = new() { "JPEG", "PNG", "WEBP", "AVIF" };

        /// <summary>
        /// 最大输入文件大小（MB）
        /// </summary>
        public int MaxInputFileSizeMB { get; set; } = 100;

        /// <summary>
        /// 质量阈值
        /// </summary>
        public QualityThresholds QualityThresholds { get; set; } = new();

        /// <summary>
        /// 高级设置
        /// </summary>
        public AdvancedSettings AdvancedSettings { get; set; } = new();
    }

    /// <summary>
    /// 质量阈值
    /// </summary>
    public class QualityThresholds
    {
        /// <summary>
        /// 最小质量评分
        /// </summary>
        public double MinQualityScore { get; set; } = 0.7;

        /// <summary>
        /// 最大压缩比
        /// </summary>
        public double MaxCompressionRatio { get; set; } = 0.5;

        /// <summary>
        /// 自动调整质量
        /// </summary>
        public bool AutoAdjustQuality { get; set; } = true;

        /// <summary>
        /// 保留原始质量阈值
        /// </summary>
        public double PreserveOriginalQualityThreshold { get; set; } = 0.95;
    }

    /// <summary>
    /// 高级设置
    /// </summary>
    public class AdvancedSettings
    {
        /// <summary>
        /// 色彩空间转换
        /// </summary>
        public string ColorSpaceConversion { get; set; }

        /// <summary>
        /// 色彩子采样
        /// </summary>
        public string ChromaSubsampling { get; set; } = "4:2:0";

        /// <summary>
        /// 锐化处理
        /// </summary>
        public bool EnableSharpening { get; set; } = false;

        /// <summary>
        /// 锐化强度
        /// </summary>
        public double SharpeningStrength { get; set; } = 0.5;

        /// <summary>
        /// 噪点抑制
        /// </summary>
        public bool EnableNoiseReduction { get; set; } = false;

        /// <summary>
        /// 对比度调整
        /// </summary>
        public double ContrastAdjustment { get; set; } = 0.0;

        /// <summary>
        /// 亮度调整
        /// </summary>
        public double BrightnessAdjustment { get; set; } = 0.0;

        /// <summary>
        /// 饱和度调整
        /// </summary>
        public double SaturationAdjustment { get; set; } = 0.0;

        /// <summary>
        /// 伽马校正
        /// </summary>
        public double GammaCorrection { get; set; } = 1.0;
    }

    /// <summary>
    /// 压缩结果
    /// </summary>
    public class CompressionResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool IsSuccess { get; set; }

        /// <summary>
        /// 错误消息
        /// </summary>
        public string ErrorMessage { get; set; }

        /// <summary>
        /// 取消原因
        /// </summary>
        public string CancelReason { get; set; }

        /// <summary>
        /// 压缩比例
        /// </summary>
        public double CompressionRatio { get; set; }

        /// <summary>
        /// 质量评分
        /// </summary>
        public double QualityScore { get; set; }

        /// <summary>
        /// 执行耗时（毫秒）
        /// </summary>
        public long ExecutionDuration { get; set; }

        /// <summary>
        /// 输出文件路径
        /// </summary>
        public string OutputFilePath { get; set; }

        /// <summary>
        /// 输出文件URL
        /// </summary>
        public string OutputFileUrl { get; set; }

        /// <summary>
        /// 节省的存储空间（字节）
        /// </summary>
        public long SpaceSaved { get; set; }

        /// <summary>
        /// 节省空间百分比
        /// </summary>
        public double SpaceSavedPercentage { get; set; }

        /// <summary>
        /// 处理的像素数量
        /// </summary>
        public long ProcessedPixels { get; set; }

        /// <summary>
        /// 处理速度（像素/秒）
        /// </summary>
        public double ProcessingSpeedPixelsPerSecond { get; set; }

        /// <summary>
        /// 压缩详情
        /// </summary>
        public Dictionary<string, object> Details { get; set; } = new();

        /// <summary>
        /// 警告信息
        /// </summary>
        public List<string> Warnings { get; set; } = new();

        /// <summary>
        /// 质量损失评估
        /// </summary>
        public QualityLossAssessment QualityLossAssessment { get; set; } = new();
    }

    /// <summary>
    /// 质量损失评估
    /// </summary>
    public class QualityLossAssessment
    {
        /// <summary>
        /// 整体质量损失（0-1，0表示无损失）
        /// </summary>
        public double OverallQualityLoss { get; set; }

        /// <summary>
        /// 清晰度损失
        /// </summary>
        public double SharpnessLoss { get; set; }

        /// <summary>
        /// 色彩损失
        /// </summary>
        public double ColorLoss { get; set; }

        /// <summary>
        /// 细节损失
        /// </summary>
        public double DetailLoss { get; set; }

        /// <summary>
        /// 压缩伪影程度
        /// </summary>
        public double CompressionArtifacts { get; set; }

        /// <summary>
        /// 视觉差异程度
        /// </summary>
        public double VisualDifference { get; set; }

        /// <summary>
        /// 质量等级
        /// </summary>
        public QualityGrade QualityGrade { get; set; }

        /// <summary>
        /// 是否可接受
        /// </summary>
        public bool IsAcceptable { get; set; }
    }

    /// <summary>
    /// 质量等级枚举
    /// </summary>
    public enum QualityGrade
    {
        /// <summary>
        /// 优秀（几乎无损失）
        /// </summary>
        Excellent = 0,

        /// <summary>
        /// 良好（轻微损失）
        /// </summary>
        Good = 1,

        /// <summary>
        /// 一般（可接受损失）
        /// </summary>
        Fair = 2,

        /// <summary>
        /// 较差（明显损失）
        /// </summary>
        Poor = 3,

        /// <summary>
        /// 很差（严重损失）
        /// </summary>
        VeryPoor = 4
    }

    /// <summary>
    /// 压缩性能指标
    /// </summary>
    public class CompressionMetrics
    {
        /// <summary>
        /// 总压缩次数
        /// </summary>
        public int TotalCompressions { get; set; }

        /// <summary>
        /// 成功次数
        /// </summary>
        public int SuccessCount { get; set; }

        /// <summary>
        /// 失败次数
        /// </summary>
        public int FailureCount { get; set; }

        /// <summary>
        /// 重试次数
        /// </summary>
        public int RetryCount { get; set; }

        /// <summary>
        /// 平均执行时间（毫秒）
        /// </summary>
        public double AverageExecutionTimeMs { get; set; }

        /// <summary>
        /// 最小执行时间（毫秒）
        /// </summary>
        public long MinExecutionTimeMs { get; set; }

        /// <summary>
        /// 最大执行时间（毫秒）
        /// </summary>
        public long MaxExecutionTimeMs { get; set; }

        /// <summary>
        /// 总压缩数据量（字节）
        /// </summary>
        public long TotalCompressedBytes { get; set; }

        /// <summary>
        /// 总节省空间（字节）
        /// </summary>
        public long TotalSpaceSaved { get; set; }

        /// <summary>
        /// 平均压缩比
        /// </summary>
        public double AverageCompressionRatio { get; set; }

        /// <summary>
        /// 平均质量评分
        /// </summary>
        public double AverageQualityScore { get; set; }

        /// <summary>
        /// 最后压缩时间
        /// </summary>
        public DateTime? LastCompressionTime { get; set; }

        /// <summary>
        /// 成功率
        /// </summary>
        public double SuccessRate => TotalCompressions > 0 ? (double)SuccessCount / TotalCompressions : 0;

        /// <summary>
        /// 平均处理速度（像素/秒）
        /// </summary>
        public double AverageProcessingSpeedPixelsPerSecond { get; set; }

        /// <summary>
        /// 更新性能指标
        /// </summary>
        public void UpdateMetrics(PhotoCompression compression)
        {
            TotalCompressions++;

            if (compression.Status == CompressionStatus.Completed)
            {
                SuccessCount++;
                TotalCompressedBytes += compression.CompressedFileSize;
                TotalSpaceSaved += compression.OriginalFileSize - compression.CompressedFileSize;
            }
            else
            {
                FailureCount++;
            }

            if (compression.ExecutionDuration > 0)
            {
                AverageExecutionTimeMs = (AverageExecutionTimeMs * (TotalCompressions - 1) + compression.ExecutionDuration) / TotalCompressions;

                if (MinExecutionTimeMs == 0 || compression.ExecutionDuration < MinExecutionTimeMs)
                    MinExecutionTimeMs = compression.ExecutionDuration;

                if (compression.ExecutionDuration > MaxExecutionTimeMs)
                    MaxExecutionTimeMs = compression.ExecutionDuration;
            }

            AverageCompressionRatio = (AverageCompressionRatio * (TotalCompressions - 1) + compression.CompressionRatio) / TotalCompressions;
            AverageQualityScore = (AverageQualityScore * (TotalCompressions - 1) + compression.QualityScore) / TotalCompressions;

            LastCompressionTime = compression.CompressionTime ?? DateTime.Now;
        }
    }

    /// <summary>
    /// 压缩历史
    /// </summary>
    public class CompressionHistory
    {
        /// <summary>
        /// 操作类型
        /// </summary>
        public CompressionAction Action { get; set; }

        /// <summary>
        /// 操作描述
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 操作时间
        /// </summary>
        public DateTime ActionTime { get; set; }

        /// <summary>
        /// 操作者ID
        /// </summary>
        public Guid? OperatorId { get; set; }

        /// <summary>
        /// 操作者名称
        /// </summary>
        public string OperatorName { get; set; }

        /// <summary>
        /// 额外数据
        /// </summary>
        public Dictionary<string, object> AdditionalData { get; set; } = new();
    }

    /// <summary>
    /// 压缩操作枚举
    /// </summary>
    public enum CompressionAction
    {
        /// <summary>
        /// 创建
        /// </summary>
        Created = 0,

        /// <summary>
        /// 开始
        /// </summary>
        Started = 1,

        /// <summary>
        /// 完成
        /// </summary>
        Completed = 2,

        /// <summary>
        /// 失败
        /// </summary>
        Failed = 3,

        /// <summary>
        /// 取消
        /// </summary>
        Cancelled = 4,

        /// <summary>
        /// 重试
        /// </summary>
        Retry = 5,

        /// <summary>
        /// 暂停
        /// </summary>
        Paused = 6,

        /// <summary>
        /// 恢复
        /// </summary>
        Resumed = 7
    }

    /// <summary>
    /// 压缩统计
    /// </summary>
    public class CompressionStatistics
    {
        /// <summary>
        /// 原始文件大小
        /// </summary>
        public long OriginalFileSize { get; set; }

        /// <summary>
        /// 压缩后文件大小
        /// </summary>
        public long CompressedFileSize { get; set; }

        /// <summary>
        /// 压缩比例
        /// </summary>
        public double CompressionRatio { get; set; }

        /// <summary>
        /// 节省的空间（字节）
        /// </summary>
        public long SpaceSaved { get; set; }

        /// <summary>
        /// 节省空间百分比
        /// </summary>
        public double SpaceSavedPercentage { get; set; }

        /// <summary>
        /// 质量评分
        /// </summary>
        public double QualityScore { get; set; }

        /// <summary>
        /// 执行耗时
        /// </summary>
        public long ExecutionDuration { get; set; }

        /// <summary>
        /// 压缩时间
        /// </summary>
        public DateTime? CompressionTime { get; set; }

        /// <summary>
        /// 压缩类型
        /// </summary>
        public CompressionType CompressionType { get; set; }

        /// <summary>
        /// 目标格式
        /// </summary>
        public string TargetFormat { get; set; }

        /// <summary>
        /// 状态描述
        /// </summary>
        public string GetStatusDescription()
        {
            return CompressionRatio switch
            {
                < 0.1 => "极高压缩",
                < 0.3 => "高压缩",
                < 0.5 => "中等压缩",
                < 0.8 => "轻度压缩",
                < 1.0 => "轻微压缩",
                _ => "文件增大"
            };
        }
    }

    /// <summary>
    /// 批量压缩任务
    /// </summary>
    public class BatchCompressionTask : FullAuditedEntity<Guid>, IMultiTenant
    {
        /// <summary>
        /// 租户ID
        /// </summary>
        public virtual Guid? TenantId { get; protected set; }

        /// <summary>
        /// 任务名称
        /// </summary>
        [Required]
        [MaxLength(200)]
        public virtual string Name { get; protected set; }

        /// <summary>
        /// 任务描述
        /// </summary>
        [MaxLength(1000)]
        public virtual string Description { get; protected set; }

        /// <summary>
        /// 任务状态
        /// </summary>
        public virtual BatchCompressionStatus Status { get; protected set; }

        /// <summary>
        /// 照片ID列表
        /// </summary>
        public virtual List<Guid> PhotoIds { get; protected set; }

        /// <summary>
        /// 压缩配置
        /// </summary>
        public virtual CompressionConfiguration Configuration { get; protected set; }

        /// <summary>
        /// 批量压缩参数
        /// </summary>
        public virtual BatchCompressionParameters Parameters { get; protected set; }

        /// <summary>
        /// 创建者ID
        /// </summary>
        public virtual Guid? CreatorId { get; protected set; }

        /// <summary>
        /// 创建者名称
        /// </summary>
        [MaxLength(200)]
        public virtual string CreatorName { get; protected set; }

        /// <summary>
        /// 开始时间
        /// </summary>
        public virtual DateTime? StartTime { get; protected set; }

        /// <summary>
        /// 完成时间
        /// </summary>
        public virtual DateTime? CompletionTime { get; protected set; }

        /// <summary>
        /// 批量压缩结果
        /// </summary>
        public virtual BatchCompressionResult Result { get; protected set; }

        /// <summary>
        /// 批量压缩进度
        /// </summary>
        public virtual BatchCompressionProgress Progress { get; protected set; }

        protected BatchCompressionTask()
        {
            PhotoIds = new List<Guid>();
            Configuration = new CompressionConfiguration();
            Parameters = new BatchCompressionParameters();
            Result = new BatchCompressionResult();
            Progress = new BatchCompressionProgress();
        }

        public BatchCompressionTask(
            Guid id,
            string name,
            List<Guid> photoIds,
            CompressionConfiguration configuration = null,
            BatchCompressionParameters parameters = null,
            Guid? creatorId = null,
            string creatorName = null,
            Guid? tenantId = null) : base(id)
        {
            Name = name;
            PhotoIds = photoIds ?? new List<Guid>();
            Configuration = configuration ?? new CompressionConfiguration();
            Parameters = parameters ?? new BatchCompressionParameters();
            CreatorId = creatorId;
            CreatorName = creatorName;
            TenantId = tenantId;
            Status = BatchCompressionStatus.Pending;

            Result = new BatchCompressionResult();
            Progress = new BatchCompressionProgress();
        }

        /// <summary>
        /// 开始批量压缩
        /// </summary>
        public virtual void StartBatchCompression()
        {
            Status = BatchCompressionStatus.Running;
            StartTime = DateTime.Now;
            Progress.StartTime = StartTime;
        }

        /// <summary>
        /// 完成批量压缩
        /// </summary>
        public virtual void CompleteBatchCompression()
        {
            Status = BatchCompressionStatus.Completed;
            CompletionTime = DateTime.Now;
            Progress.EndTime = CompletionTime;
            Progress.Duration = Progress.CalculateDuration();
        }

        /// <summary>
        /// 取消批量压缩
        /// </summary>
        public virtual void CancelBatchCompression(string reason = null)
        {
            Status = BatchCompressionStatus.Cancelled;
            CompletionTime = DateTime.Now;
            Progress.EndTime = CompletionTime;
            Result.CancelReason = reason;
        }

        /// <summary>
        /// 更新进度
        /// </summary>
        public virtual void UpdateProgress(int processedCount, int successCount, int failureCount)
        {
            Progress.ProcessedCount = processedCount;
            Result.SuccessCount = successCount;
            Result.FailureCount = failureCount;
            Progress.UpdatePercentage();

            if (processedCount >= PhotoIds.Count)
            {
                CompleteBatchCompression();
            }
        }

        /// <summary>
        /// 检查是否已完成
        /// </summary>
        public virtual bool IsCompleted()
        {
            return Status == BatchCompressionStatus.Completed ||
                   Status == BatchCompressionStatus.Failed ||
                   Status == BatchCompressionStatus.Cancelled;
        }
    }

    /// <summary>
    /// 批量压缩状态枚举
    /// </summary>
    public enum BatchCompressionStatus
    {
        /// <summary>
        /// 等待中
        /// </summary>
        Pending = 0,

        /// <summary>
        /// 运行中
        /// </summary>
        Running = 1,

        /// <summary>
        /// 已完成
        /// </summary>
        Completed = 2,

        /// <summary>
        /// 失败
        /// </summary>
        Failed = 3,

        /// <summary>
        /// 已取消
        /// </summary>
        Cancelled = 4,

        /// <summary>
        /// 部分完成
        /// </summary>
        PartiallyCompleted = 5
    }

    /// <summary>
    /// 批量压缩参数
    /// </summary>
    public class BatchCompressionParameters
    {
        /// <summary>
        /// 并发处理数量
        /// </summary>
        public int ConcurrencyCount { get; set; } = 1;

        /// <summary>
        /// 批量大小
        /// </summary>
        public int BatchSize { get; set; } = 10;

        /// <summary>
        /// 失败时是否继续
        /// </summary>
        public bool ContinueOnFailure { get; set; } = true;

        /// <summary>
        /// 最大失败数量
        /// </summary>
        public int MaxFailures { get; set; } = 10;

        /// <summary>
        /// 是否跳过已压缩的文件
        /// </summary>
        public bool SkipAlreadyCompressed { get; set; } = false;

        /// <summary>
        /// 是否创建备份
        /// </summary>
        public bool CreateBackup { get; set; } = false;

        /// <summary>
        /// 备份路径
        /// </summary>
        public string BackupPath { get; set; }

        /// <summary>
        /// 是否发送通知
        /// </summary>
        public bool SendNotification { get; set; } = true;

        /// <summary>
        /// 通知邮箱列表
        /// </summary>
        public List<string> NotificationEmails { get; set; } = new();
    }

    /// <summary>
    /// 批量压缩结果
    /// </summary>
    public class BatchCompressionResult
    {
        /// <summary>
        /// 总数量
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// 成功数量
        /// </summary>
        public int SuccessCount { get; set; }

        /// <summary>
        /// 失败数量
        /// </summary>
        public int FailureCount { get; set; }

        /// <summary>
        /// 跳过数量
        /// </summary>
        public int SkippedCount { get; set; }

        /// <summary>
        /// 是否成功
        /// </summary>
        public bool IsSuccess => FailureCount == 0 && SuccessCount > 0;

        /// <summary>
        /// 成功率
        /// </summary>
        public double SuccessRate => TotalCount > 0 ? (double)SuccessCount / TotalCount : 0;

        /// <summary>
        /// 总原始大小
        /// </summary>
        public long TotalOriginalSize { get; set; }

        /// <summary>
        /// 总压缩后大小
        /// </summary>
        public long TotalCompressedSize { get; set; }

        /// <summary>
        /// 总节省空间
        /// </summary>
        public long TotalSpaceSaved { get; set; }

        /// <summary>
        /// 总节省空间百分比
        /// </summary>
        public double TotalSpaceSavedPercentage => TotalOriginalSize > 0 ? (double)TotalSpaceSaved / TotalOriginalSize : 0;

        /// <summary>
        /// 平均压缩比
        /// </summary>
        public double AverageCompressionRatio => TotalOriginalSize > 0 ? (double)TotalCompressedSize / TotalOriginalSize : 0;

        /// <summary>
        /// 错误消息
        /// </summary>
        public string ErrorMessage { get; set; }

        /// <summary>
        /// 取消原因
        /// </summary>
        public string CancelReason { get; set; }

        /// <summary>
        /// 失败详情
        /// </summary>
        public Dictionary<Guid, string> FailureDetails { get; set; } = new();

        /// <summary>
        /// 成功详情
        /// </summary>
        public List<BatchCompressionSuccessDetail> SuccessDetails { get; set; } = new();
    }

    /// <summary>
    /// 批量压缩成功详情
    /// </summary>
    public class BatchCompressionSuccessDetail
    {
        /// <summary>
        /// 照片ID
        /// </summary>
        public Guid PhotoId { get; set; }

        /// <summary>
        /// 原始大小
        /// </summary>
        public long OriginalSize { get; set; }

        /// <summary>
        /// 压缩后大小
        /// </summary>
        public long CompressedSize { get; set; }

        /// <summary>
        /// 压缩比
        /// </summary>
        public double CompressionRatio { get; set; }

        /// <summary>
        /// 质量评分
        /// </summary>
        public double QualityScore { get; set; }

        /// <summary>
        /// 执行耗时
        /// </summary>
        public long ExecutionDuration { get; set; }
    }

    /// <summary>
    /// 批量压缩进度
    /// </summary>
    public class BatchCompressionProgress
    {
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime? StartTime { get; set; }

        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime? EndTime { get; set; }

        /// <summary>
        /// 总数量
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// 已处理数量
        /// </summary>
        public int ProcessedCount { get; set; }

        /// <summary>
        /// 成功数量
        /// </summary>
        public int SuccessCount { get; set; }

        /// <summary>
        /// 失败数量
        /// </summary>
        public int FailureCount { get; set; }

        /// <summary>
        /// 完成百分比
        /// </summary>
        public double Percentage { get; set; }

        /// <summary>
        /// 预估剩余时间（秒）
        /// </summary>
        public double? EstimatedRemainingSeconds { get; set; }

        /// <summary>
        /// 当前处理速度（每分钟）
        /// </summary>
        public double CurrentSpeed { get; set; }

        /// <summary>
        /// 平均处理速度（每分钟）
        /// </summary>
        public double AverageSpeed { get; set; }

        /// <summary>
        /// 执行耗时
        /// </summary>
        public TimeSpan? Duration { get; set; }

        /// <summary>
        /// 更新百分比
        /// </summary>
        public void UpdatePercentage()
        {
            if (TotalCount > 0)
            {
                Percentage = (double)ProcessedCount / TotalCount * 100;
            }
        }

        /// <summary>
        /// 计算执行耗时
        /// </summary>
        public TimeSpan CalculateDuration()
        {
            if (!StartTime.HasValue)
                return TimeSpan.Zero;

            var endTime = EndTime ?? DateTime.Now;
            return endTime - StartTime.Value;
        }

        /// <summary>
        /// 重置进度
        /// </summary>
        public void Reset()
        {
            StartTime = null;
            EndTime = null;
            TotalCount = 0;
            ProcessedCount = 0;
            SuccessCount = 0;
            FailureCount = 0;
            Percentage = 0;
            EstimatedRemainingSeconds = null;
            CurrentSpeed = 0;
            AverageSpeed = 0;
            Duration = null;
        }
    }
}